#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <mutex>
#include <condition_variable>
using namespace std;
/*************************
 *         学习使用C++线程库
 * ******************* */

void Print(int n, const std::string &s)
{
    for (int i = 0; i < n; i++)
    {
        std::cout << "线程id:" << std::this_thread::get_id() << ", i:" << i << " ," << s << std::endl;
    }
}

// int main(){
//     int n1,n2;
//     std::cin>>n1>>n2;
//     std::thread t1(Print,2,n1,"hello linux!!!");
//     std::thread t2(Print,0,n2,"hello C++!!!");

//     t1.join();
//     t2.join();
//     return 0;
// }

// int main()
// {
//     std::vector<std::thread> threads(5);
//     for (int i = 0; i < 5; i++)
//     {
//         // 移动构造
//         threads[i] = std::thread(Print, 10, "hello linux!!!" + std::to_string(i));
//     }

//     std::thread t1([](){
//         std::cout<<"hello C++!!!"<<std::endl;
//     });

//     //移动构造
//     std::thread t2(move(t1));
//     t2.join();

//     for (auto &thd : threads)
//     {
//         thd.join();
//     }

//     return 0;
// }

template <class Lock>
class LockGuard
{
public:
    LockGuard(Lock &lk) : _lk(lk)
    {
        _lk.lock();
    }
    ~LockGuard()
    {
        _lk.unlock();
    }

private:
    Lock &_lk;
};

int count = 0;
void GetTicket(int n, mutex &mtx)
{
    while (n--)
    {
        // unique_lock<mutex> lock(mtx);
        LockGuard<mutex> lk(mtx);
        ++count;
    }
}

// int main()
// {
//     mutex mtx;
//     int n1 = 10000;
//     int n2 = 10000;
//     // thread t1([&count, &n1, &mtx]()
//     //           {
//     //     for(int i=0;i<n1;i++){
//     //        unique_lock<mutex> lock(mtx);
//     //          ++count;
//     //     } });

//     // thread t2([&count, &n2, &mtx]()
//     //           {
//     //     for(int i=0;i<n2;i++){
//     //        unique_lock<mutex> lock(mtx);
//     //         ++count;
//     //     } });

//     thread t1(GetTicket,n1,ref(mtx));
//     thread t2(GetTicket,n2,ref(mtx));
//     t1.join();
//     t2.join();
//     cout << "ticket:" << count << endl;
//     return 0;
// }

/****************************
 *      双线程，奇偶交替打印
 * *********************** */

int main()
{
    int n = 100;
    mutex mtx;
    bool flag;
    std::condition_variable cv;
    int x=1;
    thread t1([&]()
              {
        for(int i=1;i<=n;i++){
            std::unique_lock<mutex> lock(mtx);
            if(flag)
                cv.wait(lock);
            ++x;
            cout<<"thread-1:"<<x<<endl;
            flag=!flag;  
            cv.notify_one();
        } });

    thread t2([&]()
              {
        for(int i=1;i<=n;i++){
            std::unique_lock<mutex> lock(mtx);
            if(!flag)
                cv.wait(lock);
            ++x;
            cout<<"thread-2:"<<x<<endl;
            flag=!flag;  
            cv.notify_one();

        } });

    t1.join();
    t2.join();
    return 0;
}